package com.tulele.vtool.wechat.token;

import com.alibaba.fastjson.JSONObject;
import com.tulele.vtool.utils.HttpClientUtils;
import com.tulele.vtool.wechat.token.common.Config;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Date;

@Slf4j
public class AccessToken {
    private String token;
    private long expires;
    private long tokenTime;
    private int redundance = 10000;
    private Config config;

    /**
     * 获取公众号全局唯一后台接口调用凭据的访问路径
     */
    private static final String ACCESSTOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";

    private String tokenName = "access_token";

    private String expiresInName = "expires_in";

    public AccessToken() {}

    public AccessToken(Config config) {
        this.config = config;
    }

    public String getToken() {
        return this.token;
    }

    public long getExpires() {
        return this.expires;
    }

    public Config getConfig() {
        return config;
    }

    public void setConfig(Config config) {
        this.config = config;
    }

    public boolean request() {
        boolean requestResult = false;
        String url = String.format(ACCESSTOKEN_URL, this.getConfig().getAppId(), this.getConfig().getAppSecret());
        if (!isValid()) {
            synchronized (this) {
                if (!isValid()) {
                    String result = HttpClientUtils.sendGet(url);
                    if (StringUtils.isNotBlank(result) && this.parseData(result)) {
                        requestResult = true;
                    }
                }
            }
        }
        return requestResult;
    }

    private boolean parseData(String data) {
        JSONObject jsonObject = JSONObject.parseObject(data);

        try {
            String token = jsonObject.get(tokenName).toString();
            if (StringUtils.isBlank(token)) {
                return false;
            } else {
                this.token = token;
                this.tokenTime = (new Date()).getTime();
                String expiresIn = jsonObject.get(expiresInName).toString();
                if (StringUtils.isBlank(expiresIn)) {
                    return false;
                } else {
                    this.expires = Long.valueOf(expiresIn);
                    return true;
                }
            }
        } catch (Exception e) {
            log.error("token 结果解析失败，token参数名称: " + tokenName + "有效期参数名称:" + expiresInName + "token请求结果:" + data);
//            e.printStackTrace();
            return false;
        }
    }

    /**
     * 是否有效 true-有效 false-失效
     * @return
     */
    public boolean isValid() {
        if (StringUtils.isBlank(this.token)) {
            return false;
        } else if (this.expires <= 0L) {
            return false;
        } else {
            return !this.isExpire();
        }
    }

    /**
     * 是否到期 true-到期 false-没到期
     * @return
     */
    private boolean isExpire() {
        Date currentDate = new Date();
        long currentTime = currentDate.getTime();
        long expiresTime = this.expires * 1000L - (long)this.redundance;
        return this.tokenTime + expiresTime <= currentTime;
    }
}
